﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;

namespace HYFloorPipeModule
{
	public class RevolvingEdge
	{
		public PointPair GetPointPair_A()
		{
			return this.m_PpA;
		}

		public void SetPointPair_A(PointPair pp)
		{
			this.m_PpA = pp;
		}

		public PointPair GetPointPair_B()
		{
			return this.m_PpB;
		}

		public PointPair GetPointPair_C()
		{
			return this.m_PpC;
		}

		public PointPair GetPointPair_D()
		{
			return this.m_PpD;
		}

		public ArcPtPair GetArcPair_AB()
		{
			return this.m_APpAB;
		}

		public ArcPtPair GetArcPair_BC()
		{
			return this.m_APpBC;
		}

		public ArcPtPair GetArcPair_CD()
		{
			return this.m_APpCD;
		}

		public ArcPtPair GetArcPair_DA()
		{
			return this.m_APpDA;
		}

		public RevolvingEdge()
		{
			this.m_bIsIn = false;
		}

		public void SetIn(bool b)
		{
			this.m_bIsIn = b;
		}

		public bool IsIn()
		{
			return this.m_bIsIn;
		}

		public bool Create(XYZ ptBase, XYZ vWidth, XYZ vLength, double dRadius)
		{
			this.m_ptBase = ptBase;
			this.m_vX = vWidth;
			this.m_vY = vLength;
			this.m_vUnitX = vWidth.Normalize();
			this.m_vUnitY = vLength.Normalize();
			this.m_dRadius = dRadius;
			this.m_PpA.Reset(this.m_ptBase, this.m_ptBase + this.m_vY, this.IsIn(), true);
			this.m_PpB.Reset(this.m_ptBase + this.m_vY, this.m_ptBase + this.m_vY + this.m_vX, this.IsIn(), false);
			this.m_PpC.Reset(this.m_ptBase + this.m_vY + this.m_vX, this.m_ptBase + this.m_vX, this.IsIn(), false);
			this.m_PpD.Reset(this.m_ptBase + this.m_vX, this.m_ptBase, this.IsIn(), false);
			return Math.Min(vWidth.GetLength(), vLength.GetLength()) > dRadius;
		}

		public bool Offset(double dA, double dB, double dC, double dD)
		{
			if (this.m_PpC.GetLength() < dD + dB + 2.0 * this.m_dRadius || this.m_PpD.GetLength() < dC + dA + 2.0 * this.m_dRadius)
			{
				return false;
			}
			this.m_PpA.Retract(dD, dB);
			this.m_PpB.Retract(dA, dC);
			this.m_PpC.Retract(dB, dD);
			this.m_PpD.Retract(dC, dA);
			this.m_PpA.Offset(dA * this.m_vUnitX);
			this.m_PpB.Offset(-dB * this.m_vUnitY);
			this.m_PpC.Offset(-dC * this.m_vUnitX);
			this.m_PpD.Offset(dD * this.m_vUnitY);
			return true;
		}

		private PointPair GetNewPP(PointPair pp)
		{
			return new PointPair(pp.First, pp.Second, pp.IsIn, pp.IsLoopFirst);
		}

		public bool CalAllVertices(double dNextAOffsetDist)
		{
			if (!this.CanDraw(2.0 * this.m_dRadius))
			{
				return false;
			}
			if (this.m_dRadius > 0.0)
			{
				this.m_APpAB.ReInitByTwoOrderPerPair(this.m_PpA, this.m_PpB, this.m_dRadius, false);
				this.m_APpBC.ReInitByTwoOrderPerPair(this.m_PpB, this.m_PpC, this.m_dRadius, false);
				this.m_APpCD.ReInitByTwoOrderPerPair(this.m_PpC, this.m_PpD, this.m_dRadius, false);
				PointPair pointPair = new PointPair(this.m_PpA.First, this.m_PpA.Second, this.m_PpA.IsIn, this.m_PpA.IsLoopFirst);
				pointPair.Offset(dNextAOffsetDist * this.m_vUnitX);
				this.m_APpDA.ReInitByTwoOrderPerPair(this.m_PpD, pointPair, this.m_dRadius, true);
				this.m_arrAllPp.Add(new PointPair(this.m_PpA.First, this.m_APpAB.Start, this.m_PpA.IsIn, this.m_PpA.IsLoopFirst));
				this.m_arrAllPp.Add(new PointPair(this.m_APpAB.End, this.m_APpBC.Start, this.m_PpB.IsIn, this.m_PpB.IsLoopFirst));
				this.m_arrAllPp.Add(new PointPair(this.m_APpBC.End, this.m_APpCD.Start, this.m_PpC.IsIn, this.m_PpC.IsLoopFirst));
				this.m_arrAllPp.Add(new PointPair(this.m_APpCD.End, this.m_APpDA.Start, this.m_PpD.IsIn, this.m_PpD.IsLoopFirst));
				this.m_arrAllAp.Add(this.GetNewAp(this.m_APpAB));
				this.m_arrAllAp.Add(this.GetNewAp(this.m_APpBC));
				this.m_arrAllAp.Add(this.GetNewAp(this.m_APpCD));
				this.m_arrAllAp.Add(this.GetNewAp(this.m_APpDA));
			}
			else
			{
				this.m_PpD.Retract(0.0, dNextAOffsetDist);
				this.m_arrAllPp.Add(this.GetNewPP(this.m_PpA));
				this.m_arrAllPp.Add(this.GetNewPP(this.m_PpB));
				this.m_arrAllPp.Add(this.GetNewPP(this.m_PpC));
				this.m_arrAllPp.Add(this.GetNewPP(this.m_PpD));
				this.m_PpD.Retract(0.0, -dNextAOffsetDist);
			}
			return true;
		}

		private ArcPtPair GetNewAp(ArcPtPair ap)
		{
			return new ArcPtPair(ap.Start, ap.Mid, ap.End, ap.IsIn, ap.IsLoopLast);
		}

		public bool CanDraw(double dMinDist)
		{
			XYZ first = this.m_PpA.First;
			XYZ second = this.m_PpC.Second;
			XYZ first2 = this.m_PpB.First;
			XYZ second2 = this.m_PpD.Second;
			return Math.Max(first.DistanceTo(second), first2.DistanceTo(second2)) >= dMinDist;
		}

		public bool CanDraw2(double dMinWDist, double dMinHDist)
		{
			double num = this.m_PpA.DistanceTo(this.m_PpC);
			double num2 = this.m_PpB.DistanceTo(this.m_PpD);
			return num + 1E-06 >= dMinWDist && num2 + 1E-06 >= dMinHDist;
		}

		public void AppendPointPairToArray(ref List<PointPair> aryPps, ref List<ArcPtPair> aryAps)
		{
			aryPps.Add(new PointPair(this.m_PpA.First, this.m_APpAB.Start, this.m_PpA.IsIn, true));
			aryPps.Add(new PointPair(this.m_APpAB.End, this.m_APpBC.Start, this.m_PpB.IsIn, false));
			aryPps.Add(new PointPair(this.m_APpBC.End, this.m_APpCD.Start, this.m_PpC.IsIn, false));
			aryPps.Add(new PointPair(this.m_APpCD.End, this.m_APpDA.Start, this.m_PpD.IsIn, false));
			aryAps.Add(this.m_APpAB);
			aryAps.Add(this.m_APpBC);
			aryAps.Add(this.m_APpCD);
			aryAps.Add(this.m_APpDA);
		}

		public RevolvingEdge(RevolvingEdge src)
		{
			this.m_PpA = src.GetPointPair_A();
			this.m_PpB = src.GetPointPair_B();
			this.m_PpC = src.GetPointPair_C();
			this.m_PpD = src.GetPointPair_D();
			this.m_APpAB = src.GetArcPair_AB();
			this.m_APpBC = src.GetArcPair_BC();
			this.m_APpCD = src.GetArcPair_CD();
			this.m_APpDA = src.GetArcPair_DA();
			this.m_bIsIn = src.IsIn();
		}

		private PointPair m_PpA = new PointPair();

		private PointPair m_PpB = new PointPair();

		private PointPair m_PpC = new PointPair();

		private PointPair m_PpD = new PointPair();

		private ArcPtPair m_APpAB = new ArcPtPair();

		private ArcPtPair m_APpBC = new ArcPtPair();

		private ArcPtPair m_APpCD = new ArcPtPair();

		private ArcPtPair m_APpDA = new ArcPtPair();

		private XYZ m_vX = new XYZ();

		private XYZ m_vY = new XYZ();

		private XYZ m_vUnitX = new XYZ();

		private XYZ m_vUnitY = new XYZ();

		private XYZ m_ptBase = new XYZ();

		private double m_dRadius;

		private bool m_bIsIn;

		public List<PointPair> m_arrAllPp = new List<PointPair>();

		public List<ArcPtPair> m_arrAllAp = new List<ArcPtPair>();
	}
}
